﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ThridGroup.ERP.DTO;
using ThridGroup.ERP.DTO.MaterielDto;
using Volo.Abp.Application.Services;
using Volo.Abp.Domain.Repositories;
using Volo.Abp.ObjectMapping;

namespace ThridGroup.ERP.RBAC
{
    /// <summary>
    /// 角色权限服务
    /// </summary>
    public class RolePermissionServices : ApplicationService, IRolePermissionServices
    {
        private readonly IRepository<RolePermission, int> _rolePermissionRepository;
        private readonly IRepository<Role, int> _roleServices;
        private readonly IRepository<Permission, int> _permissionServices;
        private readonly ILogger<RolePermissionServices> _logger;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="rolePermissionRepository">角色权限仓储</param>
        /// <param name="roleServices">角色仓储</param>
        /// <param name="permissionServices">权限仓储</param>
        /// <param name="logger">日志记录器</param>
        public RolePermissionServices(IRepository<RolePermission, int> rolePermissionRepository, IRepository<Role, int> roleServices, IRepository<Permission, int> permissionServices, ILogger<RolePermissionServices> logger)
        {
            _rolePermissionRepository = rolePermissionRepository;
            _roleServices = roleServices;
            _permissionServices = permissionServices;
            _logger = logger;
        }
        /// <summary>
        /// 添加角色权限
        /// </summary>
        /// <param name="createRolePermissionDto"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<int> AddRolePermission(CreateRolePermissionDto createRolePermissionDto)
        {
            try
            {
                // 添加日志记录
                _logger.LogInformation($"开始添加角色权限 - 角色ID: {createRolePermissionDto.RoleId}");

                // 验证输入参数
                if (createRolePermissionDto == null)
                {
                    _logger.LogError("createRolePermissionDto 为空");
                    return 0;
                }

                if (createRolePermissionDto.RoleId <= 0)
                {
                    _logger.LogError($"无效的角色ID: {createRolePermissionDto.RoleId}");
                    return 0;
                }

                if (createRolePermissionDto.PermissionId == null || createRolePermissionDto.PermissionId.Count == 0)
                {
                    _logger.LogError("权限ID列表为空");
                    return 0;
                }

                _logger.LogInformation($"权限ID列表: [{string.Join(", ", createRolePermissionDto.PermissionId)}]");

                // 检查角色是否存在
                var roleExists = await _roleServices.AnyAsync(r => r.Id == createRolePermissionDto.RoleId);
                if (!roleExists)
                {
                    _logger.LogError($"角色不存在，角色ID: {createRolePermissionDto.RoleId}");
                    return 0;
                }

                // 检查权限是否存在
                foreach (var permId in createRolePermissionDto.PermissionId)
                {
                    var permExists = await _permissionServices.AnyAsync(p => p.Id == permId);
                    if (!permExists)
                    {
                        _logger.LogError($"权限不存在，权限ID: {permId}");
                        return 0;
                    }
                }

                // 删除该角色的旧权限
                _logger.LogInformation($"准备删除角色ID: {createRolePermissionDto.RoleId} 的所有旧权限");
                var oldRolePermissions = await _rolePermissionRepository.GetListAsync(rp => rp.RoleId == createRolePermissionDto.RoleId);
                if (oldRolePermissions.Any())
                {
                    _logger.LogInformation($"找到 {oldRolePermissions.Count} 个旧权限记录");
                    await _rolePermissionRepository.DeleteManyAsync(oldRolePermissions);
                    _logger.LogInformation($"已删除角色ID: {createRolePermissionDto.RoleId} 的所有旧权限");
                }
                else
                {
                    _logger.LogInformation($"角色ID: {createRolePermissionDto.RoleId} 没有旧权限需要删除");
                }

                // 添加新权限
                var newRolePermissions = new List<RolePermission>();
                foreach (var permId in createRolePermissionDto.PermissionId)
                {
                    newRolePermissions.Add(new RolePermission
                    {
                        RoleId = createRolePermissionDto.RoleId,
                        PermissionId = permId
                    });
                }

                _logger.LogInformation($"准备添加 {newRolePermissions.Count} 个新权限");
                await _rolePermissionRepository.InsertManyAsync(newRolePermissions);
                _logger.LogInformation($"成功添加 {newRolePermissions.Count} 个新权限");

                return 1;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"添加角色权限时发生异常 - 角色ID: {createRolePermissionDto?.RoleId}");
                return 0;
            }
        }

        /// <summary>
        /// 显示所有角色
        /// </summary>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public async Task<List<RoleListDto>> QueryRole()
        {
            var roleList = await _roleServices.GetListAsync();
            var roleDtos = ObjectMapper.Map<List<Role>, List<RoleListDto>>(roleList);
            return roleDtos;
        }

        /// <summary>
        /// 连表查询角色、权限和角色权限
        /// </summary>
        /// <returns></returns>
        public async Task<List<RolePermissionListDto>> QueryRolePermission()
        {
            var query = from rp in await _rolePermissionRepository.GetQueryableAsync()
                        join r in await _roleServices.GetQueryableAsync() on rp.RoleId equals r.Id
                        join p in await _permissionServices.GetQueryableAsync() on rp.PermissionId equals p.Id
                        select new RolePermissionListDto
                        {
                            Id = rp.Id,
                            RoleId = r.Id,
                            PermissionId = p.Id,
                            RoleName = r.RoleName,
                            PermissionName = p.PermissionName
                        };
            return await query.ToListAsync();
        }

        /// <summary>
        /// 删除角色权限
        /// </summary>
        /// <param name="id">角色权限Id</param>
        /// <returns></returns>
        public async Task DeleteRolePermission(int id)
        {
            await _roleServices.DeleteDirectAsync(a => a.Id == id);
        }

        /// <summary>
        /// 获取单条角色权限（用于反填）
        /// </summary>
        /// <param name="roleId">角色Id</param>
        /// <returns></returns>
        public async Task<List<RolePermissionEditDto>> GetRolePermission(List<int> roleIds)
        {
            try
            {
                _logger.LogInformation($"获取角色权限信息 - 角色IDs: [{string.Join(", ", roleIds)}]");
                
                var result = new List<RolePermissionEditDto>();
                foreach (var roleId in roleIds)
                {
                    // 查询该角色的所有权限关系
                    var rolePermissions = await _rolePermissionRepository.GetListAsync(rp => rp.RoleId == roleId);
                    
                    _logger.LogInformation($"角色ID {roleId} 找到 {rolePermissions.Count} 个权限");
                    
                    // 创建结果对象
                    var dto = new RolePermissionEditDto
                    {
                        RoleId = roleId,
                        PermissionIds = rolePermissions.Select(rp => rp.PermissionId).ToList()
                    };
                    
                    _logger.LogInformation($"角色ID {roleId} 的权限IDs: [{string.Join(", ", dto.PermissionIds)}]");
                    
                    result.Add(dto);
                }
                return result;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"获取角色权限信息时发生异常 - 角色IDs: [{string.Join(", ", roleIds)}]");
                return new List<RolePermissionEditDto>();
            }
        }

        /// <summary>
        /// 修改角色权限
        /// </summary>
        /// <param name="dto">角色权限Dto</param>
        /// <returns></returns>
        public async Task<int> UpdateRolePermission(CreateRolePermissionDto dto)
        {
            try
            {
                // 添加日志记录
                _logger.LogInformation($"开始修改角色权限 - 角色ID: {dto.RoleId}");

                // 验证输入参数
                if (dto == null)
                {
                    _logger.LogError("dto 为空");
                    return 0;
                }

                if (dto.RoleId <= 0)
                {
                    _logger.LogError($"无效的角色ID: {dto.RoleId}");
                    return 0;
                }

                if (dto.PermissionId == null || dto.PermissionId.Count == 0)
                {
                    _logger.LogError("权限ID列表为空");
                    return 0;
                }

                _logger.LogInformation($"权限ID列表: [{string.Join(", ", dto.PermissionId)}]");

                // 检查角色是否存在
                var roleExists = await _roleServices.AnyAsync(r => r.Id == dto.RoleId);
                if (!roleExists)
                {
                    _logger.LogError($"角色不存在，角色ID: {dto.RoleId}");
                    return 0;
                }

                // 检查权限是否存在
                foreach (var permId in dto.PermissionId)
                {
                    var permExists = await _permissionServices.AnyAsync(p => p.Id == permId);
                    if (!permExists)
                    {
                        _logger.LogError($"权限不存在，权限ID: {permId}");
                        return 0;
                    }
                }

                // 先删除该角色的所有权限
                var oldRolePermissions = await _rolePermissionRepository.GetListAsync(rp => rp.RoleId == dto.RoleId);
                if (oldRolePermissions.Any())
                {
                    await _rolePermissionRepository.DeleteManyAsync(oldRolePermissions);
                    _logger.LogInformation($"已删除角色ID: {dto.RoleId} 的所有旧权限");
                }

                // 再批量插入新的权限
                var newPermissions = new List<RolePermission>();
                foreach (var item in dto.PermissionId)
                {
                    newPermissions.Add(new RolePermission
                    {
                        RoleId = dto.RoleId,
                        PermissionId = item
                    });
                }
                if (newPermissions.Count > 0)
                {
                    await _rolePermissionRepository.InsertManyAsync(newPermissions);
                    _logger.LogInformation($"成功添加 {newPermissions.Count} 个角色权限关系");
                }
                else
                {
                    _logger.LogWarning("没有新的角色权限关系需要添加");
                }

                return 1;
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, $"修改角色权限时发生异常 - 角色ID: {dto?.RoleId}");
                return 0;
            }
        }

        /// <summary>
        /// 显示所有权限
        /// </summary>
        /// <returns></returns>
        public async Task<List<PermissionlistDto>> QueryPermission()
        {
            var permissionList = await _permissionServices.GetListAsync();
            var permissionDtos = ObjectMapper.Map<List<Permission>, List<PermissionlistDto>>(permissionList);
            return permissionDtos;
        }

        /// <summary>
        /// 树形角色权限级联
        /// </summary>
        /// <returns></returns>
        public async Task<List<RolePermissionTreeDto>> QueryRolePermissionTree()
        {
            var allTypes = await _permissionServices.GetListAsync();
            // 递归构建树
            List<RolePermissionTreeDto> BuildTree(int FatherPermissionId)
            {
                return allTypes
                    .Where(x => x.FatherPermissionId == FatherPermissionId)
                    .OrderBy(x => x.OrderId)
                    .Select(x => new RolePermissionTreeDto
                    {
                        //Id = x.Id,
                        //Label = x.MaterialTypeName,
                        //Children = BuildTree(x.Id)
                        Id = x.Id,
                        Label = x.PermissionName,
                        Children = BuildTree(x.Id)

                    })
                    .ToList();
            }
            // 假设根节点FatherPermissionId为0
            return BuildTree(0);
        }
    }
}
